package com.example.common_library.utils.video;

import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.os.Handler;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;

import java.io.IOException;

/**
 * Video Player
 */
public class DynamicVideoPlayer {
    private MediaPlayer mediaPlayer;
    private State state = State.IDLE;
    private OnStateChangeListener onStateChangeListener;
    private final Handler handler;
    private boolean prePause;
    private TextureView textureView;


    public DynamicVideoPlayer() {
        handler = new Handler();
        mediaPlayer = new MediaPlayer();

    }

    //重新计算video的显示位置，让其全部显示并据中
    private void updateTextureViewSizeCenter(int mVideoWidth, int mVideoHeight) {
        //x轴缩放比例
        float sx = (float) textureView.getWidth() / (float) mVideoWidth;
        //y轴缩放比例
        float sy = (float) textureView.getHeight() / (float) mVideoHeight;
        Matrix matrix = new Matrix();

        Log.e("result","videoWidth"+mVideoWidth);

        //第1步:把视频区移动到View区,使两者中心点重合.
        matrix.preTranslate((textureView.getWidth() - mVideoWidth) / 2, (textureView.getHeight() - mVideoHeight) / 2);

        //第2步:因为默认视频是fitXY的形式显示的,所以首先要缩放还原回来.
        matrix.preScale(mVideoWidth / (float) textureView.getWidth(), mVideoHeight / (float) textureView.getHeight());

        //如果视频宽度大于高度 则代表是宽屏视频 此时缩放到一边相等
        if (mVideoWidth >= mVideoHeight) {
            //第3步,等比例放大或缩小,直到视频区的一边和View一边相等.如果另一边和view的一边不相等，则留下空隙
            if (sx >= sy) {
                matrix.postScale(sy, sy, textureView.getWidth() / 2, textureView.getHeight() / 2);
            } else {
                matrix.postScale(sx, sx, textureView.getWidth() / 2, textureView.getHeight() / 2);
            }
        } else {
            //先高等比拉伸至铺满
            if (mVideoHeight >= textureView.getHeight()) {
                matrix.postScale(sx,sx,textureView.getWidth() / 2, textureView.getHeight() / 2);
            }else {
                matrix.postScale(sy, sy, textureView.getWidth() / 2, textureView.getHeight() / 2);
                //然后计算改变后的缩放比例
                float newVideoWidth = mVideoWidth * sy;
                if (newVideoWidth < textureView.getWidth()) {
                    float sxNew = (float) textureView.getWidth() / newVideoWidth;
                    matrix.postScale(sxNew, sxNew, textureView.getWidth() / 2, textureView.getHeight() / 2);
                }
            }
        }

        textureView.setTransform(matrix);
        textureView.postInvalidate();
    }

    /**
     * bind TextureView
     */
    public void setTextureView(TextureView textureView) {
        this.textureView = textureView;
        if (textureView.isAvailable()) {
            mediaPlayer.setSurface(new Surface(textureView.getSurfaceTexture()));
        } else {
            textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
                @Override
                public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                    mediaPlayer.setSurface(new Surface(surface));
                }

                @Override
                public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
                }

                @Override
                public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                    return false;
                }

                @Override
                public void onSurfaceTextureUpdated(SurfaceTexture surface) {
                }
            });
        }
    }

    public void reset() {
        mediaPlayer.reset();
        state = State.IDLE;
        if (onStateChangeListener != null) {
            onStateChangeListener.onReset();
            onStateChangeListener = null;
        }
    }

    /**
     * play url
     */
    public void setDataSource(String url) {
        try {
            mediaPlayer.setDataSource(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void seekTo(int msec) {
        try {
            mediaPlayer.seekTo(msec);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void prepare() {
        try {


            mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
                @Override
                public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                    DynamicVideoPlayer.this.updateTextureViewSizeCenter(width, height);
                }
            });
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    if (state == State.PREPAREING) {
                        if (prePause) {
                            state = State.PAUSE;
                            prePause = false;
                        } else {
                            if (onStateChangeListener != null) {
                                onStateChangeListener.onRrepareFinish();
                            }
                        }
                    }
                }
            });
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    state = State.COMPLETE;
                    if (onStateChangeListener != null) {
                        onStateChangeListener.onComplete();
                        stop();
                        release();
                    }
                }
            });

            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    Log.e("mediaplayer错误", "what:" + what + "  extra:" + extra);
                    return true;
                }
            });
            mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
                @Override
                public boolean onInfo(MediaPlayer mp, int what, int extra) {
                    if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
                        if (onStateChangeListener != null) {
                            onStateChangeListener.onRenderingStart();
                        }
                        DynamicVideoPlayer.this.refreshProgress();
                    }
                    return false;
                }
            });
            state = State.PREPAREING;
            mediaPlayer.prepareAsync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void start() {
        if (state == State.PREPAREING || state == State.COMPLETE || state == State.PAUSE) {
            mediaPlayer.start();
            state = State.PLAYING;
        }
    }

    private void refreshProgress() {
//        if (state != State.COMPLETE) {
//            return;
//        }
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (mediaPlayer == null) {
                    return;
                }
                if (onStateChangeListener != null) {
                    onStateChangeListener.onProgressUpdate(mediaPlayer.getCurrentPosition() * 1f / mediaPlayer.getDuration());

                }
                DynamicVideoPlayer.this.refreshProgress();
            }
        }, 100);
    }

    public void pause() {
        if (state == State.PREPAREING && !prePause) {
            prePause = true;
            if (onStateChangeListener != null) {
                onStateChangeListener.onPause();
            }
        } else if (state == State.PLAYING) {
            mediaPlayer.pause();
            state = State.PAUSE;
            if (onStateChangeListener != null) {
                onStateChangeListener.onPause();
            }
        }
    }

    public void stop() {
        mediaPlayer.stop();
        state = State.STOP;
        if (onStateChangeListener != null) {
            onStateChangeListener.onStop();
        }
    }

    public void release() {
        mediaPlayer.release();
        mediaPlayer = null;
        handler.removeCallbacksAndMessages(null);
    }

    public State getState() {
        return state;
    }

    public int getDuration() {
        return mediaPlayer.getDuration();
    }

    public void setVolume(float leftVolume, float rightVolume) {
        mediaPlayer.setVolume(leftVolume, rightVolume);
    }

    public void setOnStateChangeListener(OnStateChangeListener onStateChangeListener) {
        this.onStateChangeListener = onStateChangeListener;
    }

    public interface OnStateChangeListener {
        void onReset();

        void onRenderingStart();

        void onRrepareFinish();

        void onProgressUpdate(float per);

        void onPause();

        void onStop();

        void onComplete();
    }

    public enum State {
        /**
         * 空闲
         */
        IDLE,
        /**
         * 准备中
         */
        PREPAREING,
        /**
         * 播放中
         */
        PLAYING,
        /**
         * 暂停中
         */
        PAUSE,
        /**
         * 播放停止
         */
        STOP,
        /**
         * 播放结束
         */
        COMPLETE
    }
}